/** *************************************************************************
 *  @file       TSNInsight.c
 *  @brief	    P2P应用与TSNInsight应用通信的接口
 *  @date		2022/03/29 
 *  @author		junshuai.li
 *  @version	0.0.1 
编写人：李军帅
version0.0.1
1、初始版本			  
****************************************************************************/

#include "../include/tsninsight.h"



int client_fd;
struct sockaddr_in ser_addr;

 static void riprt(char *str)
 {
	 int len, i;
 
	 if (str == NULL)
		 return;
	 len = strlen(str);
	 if (len == 0) 
		 return;
 
	 for (i = 0; i < len; i++)
	 {
		 if (str[i] == '\r' || str[i] == '\n')
			 str[i] = '\0';
	 }
 }
 
 int tsninsight_get_cfgx_file(const char *filpath, const char *nam, char *val)
 {
	 FILE *fd = NULL;
	 struct file_content file;
	 char *saveptr1;
	 char *saveptr2;
	 char *pstr = NULL;
	 int i = 0;
	 int ret = -1;
 
	 if ( (NULL == filpath) || (NULL == nam) || (NULL == val))
		 return ret;
		 
	 fd = fopen(filpath, "r");
	 if (fd == NULL)
		 return ret;
	 memset(&file, 0, sizeof(file));
		 
		 //read file stream to memory
	 while (fgets(LINE(LINE_CNT), LINE_LEN, fd) != NULL)
		 LINE_CNT++;
 
		 //compare and put out the value
	 for (i = 0; i < LINE_CNT; i++)
	 {
		 if (LINE(i)[0] == '#')
			 continue;
				 
		 if ((pstr = strtok_r(LINE(i), "=", &saveptr1)) != NULL)
		 {
			 if (!strcmp(pstr, nam))
			 {
				 pstr = strtok_r(NULL, "=", &saveptr1);
				 strcpy(val, pstr);
				 riprt(val);
				 ret = 0;
				 break;
			 }
		 }
				 
		 if ((pstr = strtok_r(LINE(i), " ", &saveptr2)) != NULL)
		 {
			 if (!strcmp(pstr, nam))
			 {
				 pstr = strtok_r(NULL, " ", &saveptr2);
				 strcpy(val, pstr);
				 riprt(val);
				 ret = 0;
				 break;
			 }
		 }
	 }
	 
	 fclose(fd);
	 return ret;
 }
 


 void tsninsight_pkt_print(unsigned char* pkt, int len)
 {
	 int i = 0;
 
	 printf("-----------------------***PACKET***-----------------------\n");
	 printf("Packet Addr:%p\n", pkt);
	 for (i = 0;i < 16;i++)
	 {
		 if (i % 16 == 0)
			 printf("	   ");
		 printf(" %X ", i);
		 if (i % 16 == 15)
			 printf("\n");
	 }
 
	 for (i = 0;i < len;i++)
	 {
		 if (i % 16 == 0)
			 printf("%04X: ", i);
		 printf("%02X ", *((unsigned char*)pkt + i));
		 if (i % 16 == 15)
			 printf("\n");
	 }
	 if (len % 16 != 0)
		 printf("\n");
	 printf("-----------------------***PACKET***-----------------------\n\n");
 }


 void tsninsight_msg_sender(unsigned char *pkt,unsigned short pkt_len)
 {
 	unsigned short count = 0;
    socklen_t len;
	len = sizeof(ser_addr);
    //len = sizeof(*dst);

	if(pkt_len < 60) //长度不足60字节用0补齐
	{
		bzero(pkt+pkt_len, 2048-pkt_len);
		pkt_len = 60;
	}
   
   count =  sendto(client_fd, pkt, pkt_len, 0, (struct sockaddr*)&ser_addr, len);     
	tsninsight_pkt_print(pkt,pkt_len);
	printf("send count %d\n",count);
 }


//TSNInsight初始化函数
int tsninsight_init()
{
	unsigned char tsninsight_ip[64] = {0};
	tsninsight_get_cfgx_file(CONFIG_FILE, "tsninsight_ip", tsninsight_ip);
	//printf("tsninsight_ip=%s",tsninsight_ip);
	
	 client_fd = socket(AF_INET, SOCK_DGRAM, 0);
	 if(client_fd < 0)
	 {
		 printf("create socket fail!\n");
		 return -1;
	 }
	 
	 memset(&ser_addr, 0, sizeof(ser_addr));
	 ser_addr.sin_family = AF_INET;
	 //ser_addr.sin_family = SOCK_DGRAM;
	 inet_pton(AF_INET, tsninsight_ip, &ser_addr.sin_addr);
	 //ser_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
	 ser_addr.sin_port = htons(TSNINSIGHT_PORT);

	 return 0;
}


int tsninsight_destroy()
{
	close(client_fd);
	return 0;
}


// ************************** type_id和generate_debug_pkt()是为了手动生成北向应用报文，供调试时用的  *************************************************//
#define type_id  7
void generate_debug_pkt(unsigned char *pkt, unsigned short *len)
{
#if type_id == 1
	//类型1：北向应用获取TSNlight的数据
	int pkt_len = UDP_HEAD_LEN + sizeof(remote_manage_get_req_pkt);
	remote_manage_get_req_pkt *tmp_pkt = (remote_manage_get_req_pkt *)(pkt + UDP_HEAD_LEN);

	bzero(pkt,pkt_len);

	//UDP首部中监听端口号为8089
	*(pkt + 36) = 0x1F;
	*(pkt + 37) = 0x99;

	tmp_pkt->header.type = 7;
	tmp_pkt->header.sub_type = REMOTE_GET_REQ;
	tmp_pkt->mid = 0;
	tmp_pkt->mid = (htons)(tmp_pkt->mid);
	tmp_pkt->taskid = REMOTE_TASK_TSNLIGHT;
	tmp_pkt->taskid = (htons)(tmp_pkt->taskid);
	tmp_pkt->num = 5;
	tmp_pkt->num = (htons)(tmp_pkt->num);
	tmp_pkt->base_addr = TSNLIGHT_REG_ADDR;
	tmp_pkt->base_addr = (htonl)(tmp_pkt->base_addr);

	*len = (unsigned short)pkt_len;
#endif


#if type_id == 2
	//类型2：北向应用设置TSNlight的数据
	int pkt_len = UDP_HEAD_LEN + sizeof(remote_manage_set_req_pkt);// - sizeof(unsigned int);
	remote_manage_set_req_pkt *tmp_pkt = (remote_manage_set_req_pkt *)(pkt + UDP_HEAD_LEN);

	bzero(pkt,pkt_len);

	//UDP首部中监听端口号为8089
	*(pkt + 36) = 0x1F;
	*(pkt + 37) = 0x99;

	tmp_pkt->header.type = 7;
	tmp_pkt->header.sub_type = REMOTE_SET_REQ;
	tmp_pkt->mid = 0;
	tmp_pkt->mid = (htons)(tmp_pkt->mid);
	tmp_pkt->taskid = REMOTE_TASK_TSNLIGHT;
	tmp_pkt->taskid = (htons)(tmp_pkt->taskid);
	tmp_pkt->num = 5;
	tmp_pkt->num = (htons)(tmp_pkt->num);  //2字节数据用htons
	tmp_pkt->base_addr = TSNLIGHT_REG_ADDR;
	tmp_pkt->base_addr = (htonl)(tmp_pkt->base_addr); //4字节数据用htonl

	bzero(pkt+pkt_len ,5* sizeof(unsigned int));
	tmp_pkt->value[0] = 10;
	tmp_pkt->value[0] = (htonl)(tmp_pkt->value[0]);
	tmp_pkt->value[1] = 11;
	tmp_pkt->value[1] = (htonl)(tmp_pkt->value[1]);
	tmp_pkt->value[2] = 12;
	tmp_pkt->value[2] = (htonl)(tmp_pkt->value[2]);
	tmp_pkt->value[3] = 13;
	tmp_pkt->value[3] = (htonl)(tmp_pkt->value[3]);
	tmp_pkt->value[4] = 14;
	tmp_pkt->value[4] = (htonl)(tmp_pkt->value[4]);

	pkt_len += 5* sizeof(unsigned int);
	*len = (unsigned short)pkt_len;
#endif


#if type_id == 3	
	//类型3：北向应用获取TSN交换机的数据
	int pkt_len = UDP_HEAD_LEN + sizeof(remote_manage_get_req_pkt);
	remote_manage_get_req_pkt *tmp_pkt = (remote_manage_get_req_pkt *)(pkt + UDP_HEAD_LEN);

	bzero(pkt,pkt_len);

	//UDP首部中监听端口号为8089
	*(pkt + 36) = 0x1F;
	*(pkt + 37) = 0x99;

	tmp_pkt->header.type = 7;
	tmp_pkt->header.sub_type = REMOTE_GET_REQ;
	tmp_pkt->mid = 1;
	tmp_pkt->mid = (htons)(tmp_pkt->mid);
	tmp_pkt->taskid = REMOTE_TASK_SWITCH;
	tmp_pkt->taskid = (htons)(tmp_pkt->taskid);
	tmp_pkt->num = 1;
	tmp_pkt->num = (htons)(tmp_pkt->num);
	tmp_pkt->base_addr = 0x63c04005;  
	tmp_pkt->base_addr = (htonl)(tmp_pkt->base_addr);

	*len = (unsigned short)pkt_len;
#endif


#if type_id == 4	
	//类型4：北向应用设置TSN交换机的数据
	int pkt_len = UDP_HEAD_LEN + sizeof(remote_manage_set_req_pkt);
	remote_manage_set_req_pkt *tmp_pkt = (remote_manage_set_req_pkt *)(pkt + UDP_HEAD_LEN);

	bzero(pkt,pkt_len);

	//UDP首部中监听端口号为8089
	*(pkt + 36) = 0x1F;
	*(pkt + 37) = 0x99;

	tmp_pkt->header.type = 7;
	tmp_pkt->header.sub_type = REMOTE_SET_REQ;
	tmp_pkt->mid = 1;
	tmp_pkt->mid = (htons)(tmp_pkt->mid);
	tmp_pkt->taskid = REMOTE_TASK_SWITCH;
	tmp_pkt->taskid = (htons)(tmp_pkt->taskid);
	tmp_pkt->num = 1;
	tmp_pkt->num = (htons)(tmp_pkt->num);
	tmp_pkt->base_addr = SWITCH_RW_PREVENT_BROADCAST_STORM_ADDR;  
	tmp_pkt->base_addr = (htonl)(tmp_pkt->base_addr);

	tmp_pkt->value[0] = 0x00000000;
	tmp_pkt->value[0] = (htonl)(tmp_pkt->value[0]);
	
	pkt_len += 1* sizeof(unsigned int);
	*len = (unsigned short)pkt_len;
#endif

#if type_id == 5	
		//类型5：北向应用获取opensync寄存器信息
		int pkt_len = UDP_HEAD_LEN + sizeof(remote_manage_get_req_pkt);
		remote_manage_get_req_pkt *tmp_pkt = (remote_manage_get_req_pkt *)(pkt + UDP_HEAD_LEN);
	
		bzero(pkt,pkt_len);
	
		//UDP首部中监听端口号为9089
		*(pkt + 36) = 0x23;
		*(pkt + 37) = 0x81;
	
		tmp_pkt->header.type = 7;
		tmp_pkt->header.sub_type = REMOTE_GET_REQ;
		tmp_pkt->mid = 6;
		tmp_pkt->mid = (htons)(tmp_pkt->mid);
		tmp_pkt->taskid = REMOTE_TASK_OPENSYNC;
		tmp_pkt->taskid = (htons)(tmp_pkt->taskid);
		tmp_pkt->num = 5;
		tmp_pkt->num = (htons)(tmp_pkt->num);
		tmp_pkt->base_addr = 0x00000000;  
		tmp_pkt->base_addr = (htonl)(tmp_pkt->base_addr);
	
		*len = (unsigned short)pkt_len;
#endif
	
	
#if type_id == 6	
		//类型6：北向应用获取opensync状态信息
		int pkt_len = UDP_HEAD_LEN + sizeof(remote_manage_get_req_pkt);
		remote_manage_get_req_pkt *tmp_pkt = (remote_manage_get_req_pkt *)(pkt + UDP_HEAD_LEN);
	
		bzero(pkt,pkt_len);
	
		//UDP首部中监听端口号为9089
		*(pkt + 36) = 0x23;
		*(pkt + 37) = 0x81;
	
		tmp_pkt->header.type = 7;
		tmp_pkt->header.sub_type = REMOTE_GET_REQ;
		tmp_pkt->mid = 0;
		tmp_pkt->mid = (htons)(tmp_pkt->mid);
		tmp_pkt->taskid = REMOTE_TASK_OPENSYNC;
		tmp_pkt->taskid = (htons)(tmp_pkt->taskid);
		tmp_pkt->num = 5;
		tmp_pkt->num = (htons)(tmp_pkt->num);
		tmp_pkt->base_addr = OPENSYNC_REG_ADDR;  
		tmp_pkt->base_addr = (htonl)(tmp_pkt->base_addr);
	
		*len = (unsigned short)pkt_len;
#endif

#if type_id == 7	
			//类型7：北向应用设置opensync同步周期
			int pkt_len = UDP_HEAD_LEN + sizeof(remote_manage_set_req_pkt);
			remote_manage_set_req_pkt *tmp_pkt = (remote_manage_set_req_pkt *)(pkt + UDP_HEAD_LEN);
		
			bzero(pkt,pkt_len);
		
			//UDP首部中监听端口号为9089
			*(pkt + 36) = 0x23;
			*(pkt + 37) = 0x81;
		
			tmp_pkt->header.type = 7;
			tmp_pkt->header.sub_type = REMOTE_SET_REQ;
			tmp_pkt->mid = 6;
			tmp_pkt->mid = (htons)(tmp_pkt->mid);
			tmp_pkt->taskid = REMOTE_TASK_OPENSYNC;
			tmp_pkt->taskid = (htons)(tmp_pkt->taskid);
			tmp_pkt->num = 1;
			tmp_pkt->num = (htons)(tmp_pkt->num);
			tmp_pkt->base_addr = OPENSYNC_SYNC_PERIOD;  
			tmp_pkt->base_addr = (htonl)(tmp_pkt->base_addr);
		
			tmp_pkt->value[0] = 300;
			tmp_pkt->value[0] = (htonl)(tmp_pkt->value[0]);
			
			pkt_len += 1* sizeof(unsigned int);
			*len = (unsigned short)pkt_len;
#endif

	return;
}


